
from Queue import Queue
import copy


class Task():
    def __init__(self, taskid, coroutine):
        self.__taskId = taskid
        self.__coroutine = coroutine
        self.__sendValue = ''
        self.__beforeFirstYield = True
        self.isFinished = False

    def getTaskId(self):
        return self.__taskId

    def setYield(self):
        self.__beforeFirstYield = False

    def setValue(self, value):
        self.__sendValue = value

    def run(self):
        if (self.__beforeFirstYield):
            self.__beforeFirstYield = False
            return self.__coroutine.next()
        else:
            try:
                retval = self.__coroutine.send(self.__sendValue)
                return retval
            except StopIteration:
                self.isFinished = True
                return ""


class Scheduler():
    def __init__(self):
        self.taskQueue = Queue()
        self.maxTaskId = 0
        self.taskMap = dict()

    def scheduler(self, task):
        self.taskQueue.put(task)

    def KillTask(self, taskid):
        if not taskid in self.taskMap:
            return False
        i = 0
        while i < self.taskQueue.qsize():
            tmp = self.taskQueue.get()
            if tmp == self.taskMap[taskid]:
                del self.taskMap[taskid]
                break
            else:
                self.scheduler(tmp)
            i += 1
        return True

    def copy(self, pid):
        if not pid in self.taskMap:
            return False
        newtask = copy.deepcopy(self.taskMap[pid])
        newtaskid = self.maxTaskId + 1
        self.taskMap[newtaskid] = newtask
        self.scheduler(newtask)
        return newtask

    def newTask(self, coroutine):
        self.maxTaskId += 1
        task = Task(self.maxTaskId, coroutine)
        self.taskMap[self.maxTaskId] = task
        self.scheduler(task)
        return self.maxTaskId

    def run(self):

        while not self.taskQueue.empty():

            task = self.taskQueue.get()

            retval = task.run()

            if task.isFinished:

                tid = task.getTaskId()

                del self.taskMap[tid]

            else:

                self.scheduler(task)


'''

def task1():
    i = 0

    while i < 10:
        print "This is task 1 i is %s" % i

        i += 1

        yield


def task2():
    i = 0

    while i < 10:
        print "This is task 2 i is %s" % i

        i += 1

        yield


schedular = Scheduler()
schedular.newTask(task1())
schedular.newTask(task2())
schedular.run()
'''
